package com.translate.web.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import com.basic.service.impl.BaseServiceImpl;
import com.common.util.CopyEntity;
import com.dao.base.IBaseMapper;
import com.translate.web.dao.ITrasnlateBaseDao;
import com.translate.web.param.contract.IIdAndUserIdParam;
import com.translate.web.service.IBaseTranslateService;

public abstract class BaseTranslateServiceImpl<T> extends BaseServiceImpl<T> 
	implements IBaseTranslateService<T> {

	private static final long serialVersionUID = -1585712203424637186L;
	
	protected RedisTemplate<String, ? extends Object> redisTemplate;
	

	public BaseTranslateServiceImpl(IBaseMapper<T> mapper) {
		super(mapper);
	}

//	public <S extends IPage, VO> PageResponseData<VO> getDataByList(S pageParam, Class<VO> targetClass) {
//
//		PageResponseData<VO> dataByList = super.getDataByList(pageParam, targetClass);
//		
//		long total = dataByList.getTotal();
//		
//		if (0 == total) {
//			return dataByList;
//		}
//		
//		HashOperations<String, String, Number> opsForHash = redisTemplate.opsForHash();
//		opsForHash.put(this.getClass().getName(), "num", total);
//		
//		return dataByList;
//		
//	}
//	
//	/**
//	 * 分页查询
//	 * 
//	 * @param <S>
//	 * @param param
//	 * @param statement
//	 * @throws SQLException
//	 */
//	protected <S> void bindParam(S param, PreparedStatement statement) throws SQLException {
//
//		IPage pageParam = (IPage) param;
//
//		statement.setInt(1, pageParam.getLastId());
//		
//		HashOperations<String, String, Number> opsForHash = redisTemplate.opsForHash();
//		
//		Number number = opsForHash.get(this.getClass().getName(), "num");
//		
//		int selectCount = pageParam.getSelectCount();
//
//		
//		if (null == number) {
//			statement.setInt(2, selectCount);
//			return;
//        }
//		
//		int selectNumber = number.intValue() - selectCount * (pageParam.getPageNum() - 1);
//		
//		if (selectNumber < 0) {
//			selectNumber = 0;
//		}
//		statement.setInt(2, selectNumber);
//	}
	
	/**
	 * 获取列表并缓存
	 * @param redisTemplate
	 * @param cacheKey
	 * @return
	 */
	public List<T> listToCache(String cacheKey, int limitNumber) {
		
		ValueOperations<String, List<T>> opsForValue = (ValueOperations<String, List<T>>) redisTemplate.opsForValue();
//		
		List<T> list = opsForValue.get(cacheKey);
//		
//		if (null != list) {
//			return list;
//		}
		
		list = this.getListByLimit(limitNumber);
		
		if (0 == list.size()) {
//			opsForValue.set(cacheKey, list, 3, TimeUnit.SECONDS);
			return list;
		}
		
		parseAfter(list);
		
//		opsForValue.set(cacheKey, list, 6, TimeUnit.SECONDS);

		return list;
	}
	
	/**
	 * 获取列表并缓存
	 * @param redisTemplate
	 * @param cacheKey
	 * @return
	 */
	public T getValueFromHash(
			String cacheKey, String hashKey
	) {
		
		HashOperations<String, String, T> hashOperations = redisTemplate.opsForHash();

		return hashOperations.get(cacheKey, hashKey);
	}
	
	
	/**
	 * 获取列表并缓存
	 * @param redisTemplate
	 * @param cacheKey
	 * @return
	 */
	protected List<T> listToHash(String cacheKey, int limitNumber) {
		
		HashOperations<String, String, T> hashOperations = redisTemplate.opsForHash();
		
		List<T> list = hashOperations.values(cacheKey);
		if (null != list && 0 != list.size()) {
			return list;
		}
		
		list = dataToHash(cacheKey, limitNumber, hashOperations);
		return list;
	}

	protected List<T> dataToHash(String cacheKey, int limitNumber, HashOperations<String, String, T> hashOperations) {
		List<T> list;
		list = this.getListByLimit(limitNumber);
		
		if (0 == list.size()) {
			hashOperations.put(cacheKey, "0", getEntityInstance());
			return list;
		}
		
		parseAfter(list);
		
		for (T t : list) {
			hashOperations.put(cacheKey, getId(t)+ "", t);
		}
		return list;
	}
	
	
	protected void parseAfter(List<T> data) {}
	 
	/**
	 * 无参数查询
	 * @return
	 */
	public List<T> getListByLimit(int num) {
		
		return this.getBaseMapper().getDataByListByLimit(num);
	}
	
	protected T getArticleDetail(int id) {
		ITrasnlateBaseDao<T> baseDao = this.getBaseMapper();
		
		return baseDao.getArticleDetail(id);
	}
	
	/**
     * 获取数据详情
     * @param id
     * @param param
     * @param type
     */
	public <VO> VO getDataByIdFromCache(IIdAndUserIdParam param, Class<VO> type, String key, int time) {
		
		T dataDetail = this.getDataDetailFromCache(param, key, time);
		
		if (null == dataDetail) {
            return null;
		}
		
		return CopyEntity.copyEntity(dataDetail, type);
	}
	
	
	/**
	 * 一对多
	 */
	public <VO> List<VO> getDatasByIdFromCache(IIdAndUserIdParam param, Class<VO> type, String key, int time) {
		return entityConvertToVo(this.getDatasFromCache(param, key, time), type);
	}
	
	
	/**
	 * 获取数据详情
	 * @param param
	 * @return
	 */
	public T getDataDetail(IIdAndUserIdParam param) {
		return this.mapper.getDataByIdAndUserId(param.getId(), (int) param.getUserId());
	}
	
	
	
	/**
	 * 获取数据详情
	 * @param param
	 * @return
	 */
	public List<T> getDatasFromCache(IIdAndUserIdParam param, String key, int time) {
		
		ValueOperations<String, List<T>> opsForValue = (ValueOperations<String, List<T>>) redisTemplate.opsForValue();
//		
        List<T> value = opsForValue.get(key);
        
//		if (null != value)  {
//			return value;
//		}
		
		value = this.mapper.getDatasByIdAndUserId(param);
		
		if (0 == value.size()) {
//			opsForValue.set(key, value, 3, TimeUnit.SECONDS);
            return value;
        } 
		
//		opsForValue.set(key, value, time, TimeUnit.SECONDS);
		return value;
	}
	
	/**
	 * 根据用户id及主键id获取数据详情
	 * @param param
	 * @return
	 */
	public T getDataDetailFromCache(IIdAndUserIdParam param, String key, int time) {
		
//		ValueOperations<String, T> opsForValue = (ValueOperations<String, T>) redisTemplate.opsForValue();
//		
//        T value = opsForValue.get(key);
//        
//		if (null != value)  {
//			return value;
//		}
		
		T dataByIdAndUserId = this.mapper.getDataByIdAndUserId(param.getId(), (int) param.getUserId());
		
		if (null == dataByIdAndUserId) {
			dataByIdAndUserId = getEntityInstance();
//			opsForValue.set(key, entityInstance, 3, TimeUnit.SECONDS);
//            return entityInstance;
        } 
//		
//		opsForValue.set(key, dataByIdAndUserId, time, TimeUnit.SECONDS);
		return dataByIdAndUserId;
	}
	
	
	/**
	 * 获取文章详情
	 * @param id
	 * @param redisTemplate
	 * @param cacheKey
	 * @return
	 */
	protected T getArticleDetailToCache(int id, RedisTemplate<String, ? extends Object> redisTemplate, String cacheKey) {
		
		ValueOperations<String, List<T>> opsForValue = (ValueOperations<String, List<T>>) redisTemplate.opsForValue();
//		
		List<T> list = opsForValue.get(cacheKey);
//		
//		if (null != list) {
//			return list.get(0);
//		}
		
		T item = this.getArticleDetail(id);
		
		if (null == item) {
			
			list = new ArrayList<>(0);
			
			opsForValue.set(cacheKey, list, 3, TimeUnit.SECONDS);
			return null;
		}
		
//		list = new ArrayList<>();
//		
//		list.add(item);
//		
//		opsForValue.set(cacheKey, list, 6, TimeUnit.SECONDS);

		return item;
	}

}
